{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Performance Test"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1.17.4\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import mlearn.functional as F\n",
    "import mlearn as mlearn\n",
    "import time\n",
    "import torch\n",
    "from time import time\n",
    "import sys\n",
    "np.set_printoptions(4)\n",
    "torch.set_printoptions(4)\n",
    "print(np.__version__)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [],
   "source": [
    "EPOCHS = 100\n",
    "_inputs = np.random.randn(EPOCHS,32,3,28,28)\n",
    "_weights = np.random.randn(8,3,3,3)\n",
    "_bias = np.random.randn((8))\n",
    "padding = 3\n",
    "stride = 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 3.15\n",
    "# 4.29\n",
    "inputs = mlearn.tensor(_inputs)\n",
    "weights = mlearn.tensor(_weights,requires_grad=True)\n",
    "bias = mlearn.tensor(_bias,requires_grad=True)\n",
    "start = time()\n",
    "for e,batch in enumerate(inputs):\n",
    "    c_out = F.conv_2d_experiment(batch,weights,bias,stride,padding)\n",
    "mlearn_conv = (time() - start)\n",
    "\n",
    "c_y = c_out.sum()\n",
    "c_y.backward()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [],
   "source": [
    "inputs = torch.tensor(_inputs)\n",
    "\n",
    "w = torch.tensor(_weights,requires_grad=True)\n",
    "b = torch.tensor(_bias,requires_grad=True)\n",
    "start = time()\n",
    "for e,batch in enumerate(inputs):\n",
    "    out = torch.nn.functional.conv2d(batch,w,b,stride,padding)\n",
    "torch_conv = (time() - start)\n",
    "\n",
    "y = out.sum()\n",
    "y.backward()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "mlearn -> 0.25833\n",
      "torch  -> 0.01753\n",
      "比Pytorch慢 14.73809倍\n"
     ]
    }
   ],
   "source": [
    "print(\"mlearn -> %.5f\"%mlearn_conv)\n",
    "print(\"torch  -> %.5f\"%torch_conv)\n",
    "print(\"比Pytorch慢 %.5f倍\"%(mlearn_conv/torch_conv))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [],
   "source": [
    "# check if result is the same\n",
    "np.testing.assert_almost_equal(c_out.data,out.detach().numpy(),10) \n",
    "np.testing.assert_almost_equal(weights.grad.numpy(), w.grad.numpy(),10)\n",
    "np.testing.assert_almost_equal(bias.grad.numpy(), b.grad.numpy(),10)"
   ]
  }
 ],
 "metadata": {
  "file_extension": ".py",
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.5"
  },
  "mimetype": "text/x-python",
  "name": "python",
  "npconvert_exporter": "python",
  "pygments_lexer": "ipython3",
  "version": 3
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
